package com.weaver.qfengx.schedule;

import com.weaver.qfengx.DateUtils;
import com.weaver.qfengx.LogUtils;
import com.weaver.qfengx.StringUtils;
import com.weaver.qfengx.annotation.ParamCheck;
import weaver.interfaces.schedule.BaseCronJob;

import java.lang.reflect.Field;
import java.util.Objects;

/**
 * 封装后的计划任务基础类
 */
public abstract class BaseSchedule extends BaseCronJob {

    protected LogUtils log = new LogUtils(this.getClass());

    private String scheduleName = "封装后的计划任务基础类";

    public void setScheduleName(String name) {
        this.scheduleName = name;
    }

    protected void setLog(Class clazz) {
        this.log = new LogUtils(clazz);
    }

    public abstract void execCode() throws Exception;

    @Override
    public void execute() {
        try {
            long start = System.currentTimeMillis();
            log.writeLog("====================开始" + scheduleName + "====================> " + DateUtils.datetime());

            // 同步逻辑代码处理
            long startExecCode = System.currentTimeMillis();
            log.writeLog("开始执行参数检查 => " + DateUtils.datetime());
            boolean checkRes = checkParamAnno(this);
            log.writeLog("参数检查结果 => " + checkRes);
            if (checkRes) {
                log.writeLog("开始执行业务逻辑代码 => " + DateUtils.datetime());
                execCode();
                long costTime = System.currentTimeMillis() - startExecCode;
                log.writeLog("结束执行业务逻辑代码 => cost: " + costTime / 1000 + " 秒, [" + costTime + "], " + DateUtils.datetime());
            }

            log.writeLog("====================结束" + scheduleName + " cost: "
                    + (System.currentTimeMillis() - start) + "====================> " + DateUtils.datetime());
        } catch (Exception e) {
            log.writeLog(scheduleName + " 异常：" + e.getMessage());
            e.printStackTrace();
        }
    }

    // 参数检验检查
    protected boolean checkParamAnno(BaseSchedule baseSchedule) throws IllegalAccessException {
        // 获取所有带ParamCheck注解的属性
        Class<?> clazz = baseSchedule.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ParamCheck paramCheck = field.getAnnotation(ParamCheck.class);
            if (Objects.nonNull(paramCheck)) { // 有注解才check
                field.setAccessible(true); // 设置属性可访问
                String fieldVal = StringUtils.val(field.get(baseSchedule));
                if (StringUtils.isEmpty(fieldVal)) {
                    if (paramCheck.check()) { // 检查
                        log.writeLog("参数检查错误： " + paramCheck.errorMsg());
                        return false;
                    } else {
                        field.set(baseSchedule, paramCheck.defaultVal());
                    }
                }
            }
        }
        return true;
    }
}
